<template>
	<view class="form_container">
		<slot></slot>
	</view>
</template>

<script setup>
	import {
		ref,
		provide
	} from 'vue'

	const props = defineProps({
		modelValue: {
			type: Object,
			required: true
		},
		rules: {
			type: Object,
			default: {}
		}
	})

	// 存储所有的form-item实例
	const formItems = ref({})

	// 注册form-item
	const registerFormItem = (propName, formItem) => {
		formItems.value[propName] = formItem
	}
	//子组件查询自己是否有表单验证
	const haveValidate = (propName) => {
		if (propName === 'DEFAULT') return false;
		if (props.rules[propName] !== undefined) {
			return true;
		}
		console.warn(`无法找到${propName}对应的规则，您确定在rules中声明了吗？`)
		return false;
	}
	provide('haveValidate', haveValidate)
	// 提供注册方法给子组件
	provide('registerFormItem', registerFormItem)

	const validateMap = {
		"text": textValidate,
		"name": nameValidate,
		"idCard": idCardValidate,
		"phone": phoneValidate,
		"digit": digitValidata
	}

	// 暴露给父组件的验证方法
	const validate = () => {
		let passed = true;

		//验证是否传入rules
		if (!props.rules) {
			console.warn("需要验证请传入rules(规则参数)")
			return !passed;
		}

		const keys = Object.keys(props.rules);
		if (keys.length == 0) {
			console.warn("验证规则(rules)不能为空且字段要与v-model传入的一致")
			return !passed;
		};
		// 验证所有表单项
		keys.forEach(el => {
			if (!validateMap[props.rules[el].type]) {
				console.warn("无效的rule:" + el);
				return !passed;
			}
			if (!validateMap[props.rules[el].type](props.modelValue[el])) {
				passed = false;
				if (!formItems.value[el]) {
					console.warn(el + "不存在，请假查是否给 r-form-item 设置了prop属性")
				} else {
					formItems.value[el].validate(props.rules[el].msg);
				}
			}
		})

		return passed
	}

	//验证方法
	function textValidate(el) {
		if (el === '' || el === null || el === undefined) return false;
		return true
	}

	function phoneValidate(el) {
		// 定义手机号码的正则表达式
		const phoneRegex = /^1[3-9]\d{9}$/;
		// 使用正则表达式测试输入的手机号码
		return phoneRegex.test(el);
	}

	function idCardValidate(el) {
		// 18 位身份证正则表达式
		const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$/;
		if (!idCardRegex.test(el)) {
			return false;
		}
		// 验证校验位
		const weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
		const validateCodes = '10X98765432';
		let sum = 0;
		for (let i = 0; i < 17; i++) {
			sum += parseInt(el[i]) * weight[i];
		}
		const mod = sum % 11;
		const lastChar = el[17].toUpperCase();
		return lastChar === validateCodes[mod];
	}

	// 验证姓名是否合法
	function nameValidate(el) {
		const nameRegex = /^[\u4e00-\u9fa5]+$/;
		return nameRegex.test(el);
	}

	// 验证数字是否为合法的两位小数
	function digitValidata(el) {
		const digitRegex = /^\d+(\.\d{1,2})?$/;
		return digitRegex.test(el);
	}

	// 暴露方法给父组件
	defineExpose({
		validate
	})
</script>

<style scoped lang="scss">
	.form_container {
		width: 100%;
		height: fit-content;
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		gap: 20rpx;
	}
</style>